301和302是最常见的重定向代码,其中301是永久重定向,302是临时重定向。它们的区别是永久重定向会被浏览器缓存,而临时重定向不会。除了常见的301和302,HTTP重定向代码还有303,307和308。
原理
在HTTP中,重定向是服务器发给客户端的响应,HTTP代码为3xx
。在HTTP响应头中,Location
字段标明了重定向的目的地址。
302临时重定向
HTTP重定向常用作从HTTP跳转到HTTPS。例如访问http://www.baidu.com
将会跳转到https://www.baidu.com
。在浏览器中抓包后,查看HTTP响应如下:
HTTP/1.1 302 Moved Temporarily
Server: bfe/1.0.8.18
Date: Fri, 28 Feb 2020 15:47:24 GMT
Content-Type: text/html
Content-Length: 161
Connection: keep-alive
Location: https://www.baidu.com/
注意到第一行302 Moved Temporarily
,说明这是一个临时重定向,重定向的结果不会被浏览器缓存。如果你再次输入http://www.baidu.com
并按下回车,你可以通过抓包看到一样的HTTP响应代码。
301永久重定向
301是永久重定向(Moved Permanently),永久意味着重定向的结果会被浏览器缓存。在浏览器中输入地址http://google.com/
,抓包后响应头如下:
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
......
当第二次访问http://google.com/
的时候,在浏览器控制台查看请求,可以看到的状态码后面有一句“from disk cache
”,说明请求实际上没有发送出,重定向被浏览器缓存下来了。
303、307和308重定向
经过前面的测试,我们知道:
- 301是永久重定向,重定向结果会被浏览器缓存;
- 302是临时重定向,重定向结果不会被缓存。
不过,如果查看HTTP状态码列表,就会发现,除了301和302,重定向代码还有303、307和308:
- 303 See Other
- 307 Temporary Redirect
- 308 Permanent Redirect
实际上,301和302重定向代码在HTTP 1.0版本就已经出现。
在HTTP 1.0规范中,要求浏览器在重定向时保持请求方法和请求主体不变。即如果一个POST
请求发到服务器,服务器返回了301或302重定向代码,浏览器应当使用POST
方法像新地址发起请求。
而部分浏览器却不按规范,发生重定向时,将POST
方法改为GET
方法来发起新的请求。
为了解决这个问题,在HTTP 1.1规范(RFC7231 和 RFC7238)中,新增了303、307和308重定向代码。
根据新的规范:
303
为临时重定向代码,在请求新的地址时,必须使用GET
方法,且重定向结果不能缓存;
307
为临时重定向代码,在请求新的地址时,应该保持原来的请求方法,且重定向结果不能缓存;
308
为永久重定向代码,在请求新的地址时,应该保持原来的请求方法,重定向结果可以缓存。
总结
状态码 | HTTP版本 | 是否缓存 | 请求方法 |
---|---|---|---|
301 | HTTP 1.0 | ✔ | 可能改变 |
302 | HTTP 1.0 | × | 可能改变 |
303 | HTTP 1.1 | × | 必须是GET |
307 | HTTP 1.1 | × | 保持原来的请求方法 |
308 | HTTP 1.1 | ✔ | 保持原来的请求方法 |